#ifndef xpack_graphic_draw_ellipse
#define xpack_graphic_draw_ellipse
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::graphic_draw_ellipse::inc
#include"define/base_type.hpp"
#include"graphic/draw/ellipse_quarter.hpp"
#include"graphic/private/rander_helper.hpp"
#include"graphic/rander_wrapper.hpp"
#include"macro/xexport.hpp"
#include"macro/xunlikely.hpp"
#include"math/point.hpp"
#pragma pop_macro("xuser")

namespace mixc::graphic_draw_ellipse::inc{
    template<bool texturing_v, class rander_t>
    inline void ellipse_core(inc::pt2wx p, uxx rx, uxx ry, rander_t const & rander){
        ::mixc::graphic_draw_ellipse_quarter::ellipse_quarter_core(rx, ry, [&](auto x, auto y, auto is_wrap){
            auto x0         = p->x - x;
            auto x1         = p->x + x - 1; // 需要 - 1，这样 texuring 步骤的 width 才正常
            auto y0         = p->y - y;
            auto y1         = p->y + y - 1;
            rander(x0, y0);
            rander(x1, y0);
            rander(x0, y1);
            rander(x1, y1);

            // 注意:
            // 使用显式 texturing 而非通用 texturing 以便能有更好的性能
            if constexpr (texturing_v and inc::is_rander_wrapper<rander_t>){
                xunlikely(not is_wrap){
                    return;
                }

                if (inc::rander_helper::get_texture_mode(rander) == inc::texture_mode_t::none){
                    return;
                }

                auto width  = x + x - 2/*左边一个像素，右边一个像素*/;
                auto x2     = x0 + 1;
                rander.texturing(x2, y0, width);
                rander.texturing(x2, y1, width);
            }
        });
    }
}

namespace mixc::graphic_draw_ellipse::origin{
    template<class rander_t>
    inline void ellipse(inc::pt2wx p, uxx rx, uxx ry, rander_t const & rander){
        if (auto thickness = inc::rander_helper::get_thickness(rander); thickness != 1){
            inc::rander_helper::thickening(rander, [&](auto const & outside_rander, auto const & inside_rander){
                inc::ellipse_core<false>(p, rx + thickness - 1, ry + thickness - 1, outside_rander);
                inc::ellipse_core<true>(p, rx, ry, inside_rander);
            });
        }
        else{
            inc::ellipse_core<true>(p, rx, ry, rander);
        }
    }

    template<class rander_t>
    inline void ellipse(uxx rx, uxx ry, rander_t const & rander){
        ellipse({}, rx, ry, rander);
    }
}
#endif

xexport_spacex(draw, mixc::graphic_draw_ellipse::origin)
